<?php
/**
 * スタッフログインパスワード変更チケット
 */
require_once dirname(__FILE__) . '/jp.php';
/**
 * スタッフログインパスワード変更チケット
 * @link http://www.evernote.com/shard/s89/sh/c330dbb6-9532-4443-9ebb-fddd59c7afe2/22be854176735fc87b3bb9fade9b07ac
 */
class Models_StaffPasswordChangeTicket
{
	/** @var クラス状態 */
	public $condition;
	/** @var 内部変数 */
	protected $var;
	/**
	 * コンストラクタ
	 */
	public function __construct($Uid, $Period= jp::当日限り有効のチケット)
	{
		$this->var = array();
		/**期限が数字でも当日有効でもない場合、当日有効にする */
		if ((!is_numeric($Period)) && ($Period != jp::当日限り有効のチケット)) {
			$Period = jp::当日限り有効のチケット;
		}
		$this->var[jp::期限] = $Period;
		$this->var[jp::保存フォルダー] = dirname(__FILE__) . '/StaffPasswordChangeTicket/databox';
		/** 保存フォルダーが未設置の場合設置する */
		if (!file_exists($this->var[jp::保存フォルダー])) {
			/** フォルダーの設置に失敗した場合、クラス状態に使用不可を設定する。 */
			if (!mkdir($this->var[jp::保存フォルダー])) {
				$this->condition = FALSE;
				return;
			}
		}
		$this->var[jp::ユニークID] = $Uid;
		$this->condition = TRUE;
		/** 有効期間外のチケットが残っている場合削除する */
		if (!$this->有効期間判定()) {
			$this->チケットを削除する();
		}
	}
	/**
	 * チケットを削除する
	 */
	public function チケットを削除する()
	{
		/** 削除済みならなにもしない*/
		if (!file_exists($this->var[jp::保存フォルダー].'/'.$this->var[jp::ユニークID])){
			return true;
		}
		$result = unlink($this->var[jp::保存フォルダー].'/'.$this->var[jp::ユニークID]);
		return $result;
	}
	/**
	 * 有効期間内であればＴＲＵＥを返す
	 */
	public function 有効期間判定()
	{
		/*チケットが存在しない場合ＦＡＬＳＥを返す*/
		if (!file_exists($this->var[jp::保存フォルダー].'/'.$this->var[jp::ユニークID])) {
			return FALSE;
		}
		$pl[jp::更新日時] = filemtime($this->var[jp::保存フォルダー].'/'.$this->var[jp::ユニークID]);
		switch ($this->var[jp::期限]) {
			case jp::当日限り有効のチケット:
				$sd = date('Ymd');
				$sd = date('Ymd',$pl[jp::更新日時]);
				if (date('Ymd') == date('Ymd',$pl[jp::更新日時])) {
					return TRUE;
				}
				break;
		}
		return FALSE;
	}
	/**
	 * 有効チケットがあるか問い合わせる
	 */
	public function exists()
	{
		/* クラス状態が「使用不可」の場合なにもしない*/
		if ($this->condition==FALSE){
			return FALSE;
		}
		if (file_exists($this->var[jp::保存フォルダー].'/'.$this->var[jp::ユニークID])) {
			return TRUE;
		}
		return FALSE;
	}
	/**
	 * チケットを発行する
	 */
	public function put()
	{
		/* クラス状態が「使用不可」の場合何もしない。*/
		if ($this->condition == FALSE) {
			return FALSE;
		}
		$ret = file_put_contents($this->var[jp::保存フォルダー].'/'.$this->var[jp::ユニークID], '');
		if ($ret === FALSE) {
			$this->condition = FALSE;
		}
		return $ret;
	}
}
/*******************************************************
 *                                    単体テストブロック
 ******************************************************/
if (class_exists ( 'SimpleActionControllerTester' )) {
	/**
	 * ユニットテストコントローラ
	 */
	class StaffPasswordChangeTicketTest extends SimpleActionControllerTester
	{
		/**
		 * コンストラクターテスト０１
		 * 保存フォルダーが未設置の場合設置されること
		 */
		public function test_constructor01()
		{
			$controller = new Models_StaffPasswordChangeTicketMoc('abc');
			$var = $controller->getValue('var');
			$ret = file_exists($var[jp::保存フォルダー]);
			$this->assertEqual($ret, TRUE);
		}
		/**
		 * コンストラクターテスト０２
		 * 有効期限切れのチケットを削除する。
		 */
		public  function test_constructor02()
		{
			$controller = new Models_StaffPasswordChangeTicketMoc('abc');
			$controller->put();
			GLOBAL $glTIME_DIFF;
			$glTIME_DIFF = 60 * 60 * 24;
			$controller2 = new Models_StaffPasswordChangeTicketMoc('abc');
			$ret  = $controller2->exists();
			$this->assertEqual($ret, FALSE);
			$glTIME_DIFF = 0;
		}
		/**
		 * 「有効チケットがあるか問い合わせる」（exists）テスト０１
		 *  UIDについて有効チケットがない場合FALSEを返す
		 */
		public function test_exists01()
		{
			$controller = new Models_StaffPasswordChangeTicketMoc('none');
			$ret = $controller->exists();
			$this->assertEqual($ret, FALSE);
		}
		/**
		 * 「チケットを発行する」（put）テスト０１
		 * チケットを発行直後、当日有効指定で同じUIDについて「有効チケットがあるか問い合わせる」を実施した結果が
		 * TRUEであること。
		 */
		public function test_put01()
		{
			$controller = new Models_StaffPasswordChangeTicket('53780c9b851208.74580417');
			$controller->put();
			unset($controller);
			$controller = new Models_StaffPasswordChangeTicket('53780c9b851208.74580417');
			$ret = $controller->exists();
			$this->assertEqual($ret, TRUE);
		}
		/**
		 * 有効期間テスト０１
		 * チケットが有効期間外の場合ＦＡＬＳＥを返す
		 */
		public function test_有効期間０１()
		{
			$controller = new Models_StaffPasswordChangeTicketMoc('abc');
			$controller->put();
			GLOBAL $glTIME_DIFF;
			$glTIME_DIFF = 60 * 60 *24;
			$ret = $controller->有効期間判定();
			$this->assertEqual($ret, FALSE);
			$glTIME_DIFF = 0;
		}
		/**
		 * 有効期間テスト０２
		 * チケットが存在しない場合ＦＡＬＳＥを返す
		 */
		public function test_有効期間０２()
		{
			$controller = new Models_StaffPasswordChangeTicketMoc('zzz');
			$controller->有効期間判定();
			$ret = $controller->有効期間判定();
			$this->assertEqual($ret, FALSE);
		}
		/**
		 * 有効期間テスト０３
		 * チケットが有効期間内の場合ＴＲＵＥを返す
		 */
		public function test_有効期間０３()
		{
			GLOBAL $glTIME_DIFF;
			$controller = new Models_StaffPasswordChangeTicketMoc('abc');
			$controller->put();
			$ret = $controller->有効期間判定();
			$this->assertEqual($ret, TRUE);
		}
		/**
		 * 被検アクションコントローラインスタンス作成
		 * (non-PHPdoc)
		 * @see SimpleActionControllerTester::setUp()
		 */
		public function setUp()
		{
			parent::setUp();
//			$this->controller = new Models_StaffPasswordChangeTicketMoc();
		}

	}
	/* headerメソッドの機能を変更し発行ヘッダを評価できるようにする*/
	runkit_function_remove('header');
	function header($string)
	{
		GLOBAL $redirectUrl;
		$redirectUrl = $string;
	}
	/** @var time関数の返却値を前後にずらす秒を設定するグローバル変数*/
	$glTIME_DIFF = 0;
	/* timeメソッドの機能を変更し実時間より指定秒ずらした時間を返すようにする */
	function 時間をずらして返すtime定義()
	{
		GLOBAL $glTIME_DIFF;
		$ret = 隠蔽time() + $glTIME_DIFF;
		return $ret;
	}
	runkit_function_rename('time', '隠蔽time');
	runkit_function_rename('時間をずらして返すtime定義','time');
	function date関数に時間をずらすtime関数を反映($format, $timestamp=null)
	{
		if ($timestamp === null) {
			$timestamp = time();
		}
		$result = 隠蔽date($format, $timestamp);
		return $result;
	}
	runkit_function_rename('date', '隠蔽date');
	runkit_function_rename('date関数に時間をずらすtime関数を反映', 'date');

	/*** テスト対象コントローラに全プロパティ参照可能メソッドを追加する */
	runkit_method_copy('Models_'.pathinfo(__FILE__)['filename'], 'getValue', 'ActionControllerTestController');
	/**
	 * テスト用にメソッドをオーバーライドしたモックアクションコントローラ
	 */
	class Models_StaffPasswordChangeTicketMoc extends Models_StaffPasswordChangeTicket
	{
		/**
		 * ZendViewをパブリックアクセスできるようにする
		 * (non-PHPdoc)
		 * @see IndexController::init()
		 */
		public function init()
		{
			/*** CLI起動はviewのインスタンスがない */
			if (!isset($this->view)) {
				$this->view = new stdClass();
			}
			parent::init();
		}
		/**
		 * リダイレクトをリダイレクト先検証用に書き換える
		 * (non-PHPdoc)
		 * @see Zend_Controller_Action::_redirect()
		 */
		public function _redirect($url) {
			GLOBAL $redirectUrl;
			$redirectUrl = $url;
		}
	}
}